﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DeptEmpl;

namespace LinqForDeptEmpl
{
    class Program
    {

        public static List<Dept> departments = new List<Dept>(){  new Dept(1,"Dnepropetrovsk"),
                                                                new Dept(2,"Kiev"),
                                                                new Dept(3,"Lvov"),
                                                                new Dept(4,"Donesck"),
                                                                new Dept(5,"Harkov"),
                                                                new Dept(6,"Odessa"),
                                                                new Dept(7,"Hacapetovka"),
                                                                new Dept(8,"Sevastopol"),
                                                                new Dept(9,"Yalta"),
                                                                new Dept(10,"Simferopol"),
                                                                new Dept(11,"Alyshta")};
        public static List<Empl> employees = new List<Empl>() {   new Empl(1,"Dyadka","Dyadkovich",4),
                                                            new Empl(2,"Tetka","Tetkovna",1),
                                                            new Empl(3,"Makar","Makarovich",5),
                                                            new Empl(4,"Alexandr","Alexandrovich",7),
                                                            new Empl(5,"Andrey","Andreevich",3),
                                                            new Empl(6,"Andrey","Andreevich",2),
                                                            new Empl(7,"Vasiliy","sdfg",9),
                                                            new Empl(8,"Vasiliy","sdf",8),
                                                            new Empl(9,"Vasiliy","poi",7),
                                                            new Empl(10,"Vasiliy","wedf",9),
                                                            new Empl(11,"Vasiliy","mnbv",6),
                                                            new Empl(12,"Vasiliy","qwerfg",4),
                                                            new Empl(13,"Vasiliy","edfv",3),
                                                            new Empl(14,"Vasiliy","asdf",2),
                                                            new Empl(15,"Vasiliy","yhgb ",8),
                                                            new Empl(16,"Vasiliy","mnjh ",9),
                                                            new Empl(17,"Vasiliy","zxd ",8),
                                                            new Empl(18,"Alexandr","Alexandrovich",7),
                                                            new Empl(19,"Vasiliy","Alexandrovich",7),
        };

        static void Main(string[] args)
        {
            Linq1();
            Linq2();
            Linq3();
            Linq4();
            Linq5();
            Linq6();
            Linq7();
            Linq8();
            Linq9();
            Linq10();
            Console.ReadLine();
        }

        /// <summary>
        /// 1 - Выведите список городов, где находятся подразделения компании.
        /// </summary>
        public static void Linq1()
        {
            var CityList = (
                from city in departments
                orderby city.City
                select city.City)
                .Distinct();

            Console.WriteLine("City List:");
            foreach (var x in CityList)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// 2 - Выведите список имен работников (без повторов, упорядочен по алфавиту).
        /// </summary>
        public static void Linq2()
        {
            var EmplList = (
                from empl in employees
                orderby empl.FirstName
                select empl.FirstName)
                .Distinct();

            Console.WriteLine("Employeers firstname list:");
            foreach (var x in EmplList)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// 3 - Посчитайте, сколько работников у компании в заданном подразделении (номер)
        /// </summary>
        public static void Linq3()
        {
            var EmplCount = (
                from empl in employees
                where empl.DeptId == 7
                select empl.DeptId)
                .Count();

            Console.WriteLine("Employeers in deptid = 7:");
            Console.WriteLine(EmplCount);
        }

        /// <summary>
        /// 4 - Получите список количества работников в каждом подразделении (номер). Упорядочить по убыванию числа работников.
        /// </summary>
        public static void Linq4()
        {
            var EmplCount =
                from empl in employees
                group empl by empl.DeptId into deptGroup
                orderby deptGroup.Count() descending
                select new { DepartmentId = deptGroup.Key, EmpleersCount = deptGroup.Count() };

            Console.WriteLine("Employeers count in departents:");
            foreach (var x in EmplCount)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// 5 - Получите список количества работников в каждом подразделении (номер).
        /// Упорядочить по названиям городов, где располагается подразделение.
        /// </summary>
        public static void Linq5()
        {
            var EmplCount =
                from empl in employees
                join dept in departments on empl.DeptId equals dept.Id
                group dept by dept.City into deptGroup
                orderby deptGroup.Key
                select new { City = deptGroup.Key, Amount = deptGroup.Count() };

            Console.WriteLine("Employeers count in departents:");
            foreach (var x in EmplCount)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// 6 - Выберите список городов, содержащие букву 'D' в начале слова
        /// </summary>
        public static void Linq6()
        {
            var DeptList =
                from dept in departments
                where dept.City.StartsWith("D")
                select dept.City;

            Console.WriteLine("City lists with bigin on 'D':");
            foreach (var x in DeptList)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// 7 - Выберите список всех городов, содержащие букву 't' в середине слова
        /// и соответствующее количество работников напротив каждого названия.
        /// Учесть, что в таблице подразделений может быть город, в котором отсутствуют работники,
        /// и в таблице работников могут быть такие, для которых данные поля DptId = NULL.
        /// </summary>
        public static void Linq7()
        {
            var DeptList =
                from empl in employees
                join dept in departments on empl.DeptId equals dept.Id
                where dept.City.Contains('t')
                group dept by dept.City into deptGroup
                select new { deptGroup.Key, Count = deptGroup.Count() };

            Console.WriteLine("Employeers count in departents with 't':");
            foreach (var x in DeptList)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        ///  8 - Выберите список людей, имеющих однофамильцев. Упорядочить по алфавиту.
        /// </summary>
        public static void Linq8()
        {
            var EqualName =
                (from empl in employees
                 from empl2 in employees
                 where empl.Id != empl2.Id && empl.LastName == empl2.LastName
                 orderby empl.LastName, empl.FirstName
                 select new { empl.FirstName, empl.LastName }).Distinct();

            Console.WriteLine("Employeers with the same lastnames");
            foreach (var x in EqualName)
            {
                Console.WriteLine(x);
            }
        }


        /// <summary>
        /// 9 - Выберите список людей, имеющих несколько полных совпадений имени и фамилии из города 'Hacapetovka' и упорядочить по именам.
        /// </summary>
        public static void Linq9()
        {
            var EqualName =
                (from dept in departments
                 where dept.City == "Hacapetovka"
                 from empl in employees
                 from empl2 in employees
                 where empl.Id != empl2.Id && empl.LastName == empl2.LastName && empl.FirstName == empl2.FirstName && empl.DeptId == dept.Id
                 orderby empl.FirstName
                 select new { empl.FirstName, empl.LastName }).Distinct();

            Console.WriteLine("Employeers with the same lastnames and names from Hacapetovka");
            foreach (var x in EqualName)
            {
                Console.WriteLine(x);
            }
        }

        /// <summary>
        /// --10 - Получите список городов с количеством работников с именем 'Vasiliy' более 2.
        ///-- Упорядочить по номеру подразделения.
        /// </summary>
        public static void Linq10()
        {
            var EqualName =
                         (from empl in employees
                         join dept in departments on empl.DeptId equals dept.Id
                         where empl.FirstName == "Vasiliy"
                         group dept by dept.City into deptgroup
                         orderby deptgroup.Key
                         select new { City = deptgroup.Key, Amount = deptgroup.Count() }).Where(d => d.Amount > 2);

            Console.WriteLine("Cities with employeers 'Vasiliy' > 2");
            foreach (var x in EqualName)
            {
                Console.WriteLine(x);
            }

        }

    }
}
